package worldinruin.core.imp;

import worldinruin.core.IResources;

/**
 * 
 * Immutable
 *
 */

public class Resources implements IResources {
	
	private static final long serialVersionUID = 2240483135756065327L;
	private final int food;
	private final int iron;
	private final int stone;
	private final int wood;
	
	/**
	 * Creates a resource object with 0 resources.
	 */
	public Resources() {
		this(0, 0, 0);
	}
	
	/**
	 * Creates a resource object with the given values.
	 * @param iron Iron value.
	 * @param stone Stone value.
	 * @param wood Wood value.
	 */
	public Resources(int iron, int stone, int wood){
		this(0, iron, stone, wood);
	}
	
	/**
	 * Creates a resource object with the given values and checks for
	 * legal parameters.
	 * @param food Food value.
	 * @param iron Iron value.
	 * @param stone Stone value.
	 * @param wood Wood value.
	 */
	public Resources(int food, int iron, int stone, int wood) {
		
		if (food < 0 || iron < 0 || stone < 0 || wood < 0){
			throw new IllegalArgumentException("Resource field cannot be sub-zero");
		}
		
		this.food = food;
		this.iron = iron;
		this.stone = stone;
		this.wood = wood;
	}
	
	/* (non-Javadoc)
	 * @see worldinruin.core.imp.IResoucres#getFood()
	 */
	public int getFood() {
		return food;
	}
	/* (non-Javadoc)
	 * @see worldinruin.core.imp.IResoucres#getIron()
	 */
	public int getIron() {
		return iron;
	}
	/* (non-Javadoc)
	 * @see worldinruin.core.imp.IResoucres#getStone()
	 */
	public int getStone() {
		return stone;
	}
	/* (non-Javadoc)
	 * @see worldinruin.core.imp.IResoucres#getWood()
	 */
	public int getWood() {
		return wood;
	}
	/* (non-Javadoc)
	 * @see worldinruin.core.imp.IResoucres#add(worldinruin.core.imp.Resources)
	 */
	public IResources add(IResources r){
		return new Resources(this.food + r.getFood(), this.iron + r.getIron(), this.stone + r.getStone(),
				this.wood + r.getWood());
	}
	
	/* (non-Javadoc)
	 * @see worldinruin.core.imp.IResoucres#multiply(int)
	 */
	public IResources multiply(int i){
		return new Resources(this.food * i, this.iron * i, this.stone * i, this.wood * i);
	}
	

	/* (non-Javadoc)
	 * @see worldinruin.core.imp.IResoucres#addFood(int)
	 */
	public IResources addFood(int food){
		return new Resources(this.food + food, this.iron, this.stone,
				this.wood);
	}
	
	/* (non-Javadoc)
	 * @see worldinruin.core.imp.IResoucres#addIron(int)
	 */
	public IResources addIron(int iron){
		return new Resources(this.food, this.iron + iron, this.stone,
				this.wood);
	}
	
	/* (non-Javadoc)
	 * @see worldinruin.core.imp.IResoucres#addStone(int)
	 */
	public IResources addStone(int stone){
		return new Resources(this.food, this.iron, this.stone + stone,
				this.wood);
	}
	/* (non-Javadoc)
	 * @see worldinruin.core.imp.IResoucres#addWood(int)
	 */
	public IResources addWood(int wood){
		return new Resources(this.food, this.iron, this.stone,
				this.wood + wood);
	}
	
	/* (non-Javadoc)
	 * @see worldinruin.core.imp.IResoucres#isAffordable(worldinruin.core.imp.Resources)
	 */
	public boolean isAffordable(IResources r){
		return this.food >= r.getFood() && this.iron >= r.getIron() &&
				this.stone >= r.getStone() && this.wood >= r.getWood();
	}
	
	/* (non-Javadoc)
	 * @see worldinruin.core.imp.IResoucres#subtract(worldinruin.core.imp.Resources)
	 */
	public IResources subtract(IResources r){
		return new Resources(this.food - r.getFood(), this.iron - r.getIron(), this.stone - r.getStone(),
				this.wood - r.getWood());		
	}
	
	/* (non-Javadoc)
	 * @see worldinruin.core.imp.IResoucres#equals(java.lang.Object)
	 */
	public boolean equals(Object obj) {
		if(obj == null || obj.getClass() != this.getClass()) {
			return false;
		}
		Resources r = (Resources) obj;
		return this.food == r.getFood() && this.iron == r.getIron() && this.stone == r.getStone() && this.wood == r.getWood();
	}

}
